package com.three.db.shard.time;

import com.dangdang.ddframe.rdb.sharding.api.ShardingValue;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm;
import com.google.common.collect.Range;
import com.three.db.shard.base.TimeSingleKeyTableShardingAlgorithm;

import java.time.temporal.ChronoUnit;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;

import static com.three.db.shard.base.TimeUtils.*;

/**
 * Created by ziqingwang on 2017/6/1 0001.
 */
public class TbShardingAlgorithm4Mounth implements TimeSingleKeyTableShardingAlgorithm<Date> {
    @Override
    public boolean match(ChronoUnit chronoUnit) {
        return chronoUnit.equals(ChronoUnit.MONTHS);
    }
    @Override
    public String doEqualSharding(Collection<String> availableTargetNames, ShardingValue<Date> shardingValue) {
        return availableTargetNames.stream()
                .filter(tb -> tb.endsWith(getMounthKey(shardingValue.getValue())))
                .findFirst()
                .get();
    }

    @Override
    public Collection<String> doInSharding(Collection<String> availableTargetNames, ShardingValue<Date> shardingValue) {
        int size=availableTargetNames.size();
        Collection<String> result = new LinkedHashSet<>(size);
        for (Date date : shardingValue.getValues()) {
            String mounth=getMounthKey(date);
            for (String tableName : availableTargetNames) {
                if (tableName.endsWith(mounth)) {
                    result.add(tableName);
                }
            }
        }
        return result;
    }

    @Override
    public Collection<String> doBetweenSharding(Collection<String> availableTargetNames, ShardingValue<Date> shardingValue) {
        int size=availableTargetNames.size();
        Collection<String> result= new LinkedHashSet<>(size);
        Range<Date> range = shardingValue.getValueRange();
        int start=getMounth(range.lowerEndpoint())-1;
        int end=getMounth(range.upperEndpoint())-1;
        Object[] array=availableTargetNames.toArray();
        for(int i=0;i<size;i++){
            if(i>=start&&i<=end)result.add((String)array[i]);
        }
        return result;
    }
}
